package io.bdmc.common.nbapi.sdk.analyze;

import java.text.SimpleDateFormat;
import java.util.HashMap;

import io.bdmc.modules.bss.model.alarm.AlarmHKData;

import java.util.Date;
public class ParsingMessage 
{
	public static HashMap<Integer,String> messageIdDic = new HashMap<Integer,String>();
	public static HashMap<Integer,String> devTypeDic = new HashMap<Integer,String>();
	public static HashMap<Integer,String> msgType = new HashMap<Integer,String>();
	public static HashMap<Integer,String> paramType = new HashMap<Integer,String>();
	public static HashMap<Integer,String> statusType = new HashMap<Integer,String>();

	public ParsingMessage() {  
		messageIdDic.clear();
		messageIdDic.put(1, "心跳");
		messageIdDic.put(2, "报警");
		messageIdDic.put(3, "消音");
		messageIdDic.put(4, "自检");
		messageIdDic.put(5, "故障");
		messageIdDic.put(6, "信号查询");
		messageIdDic.put(7, "注册");
		messageIdDic.put(8, "注销");
		messageIdDic.put(9, "保活");
		messageIdDic.put(0x0A, "配置参数上报");
		messageIdDic.put(0x90, "下发参数");
		messageIdDic.put(0x93, "下发安全配置");

		devTypeDic.clear();
		devTypeDic.put(0x02, "烟感");
		devTypeDic.put(0x03, "燃气");
		devTypeDic.put(0x82, "多通道协议烟感");
		devTypeDic.put(0x83, "多通道协议燃气");
		devTypeDic.put(0x84, "组合电气火灾");
		devTypeDic.put(0x85, "单相电气火灾");
		devTypeDic.put(0x86, "用水");

		msgType.clear();
		msgType.put(0, "无事件");
		msgType.put(3, "故障");
		msgType.put(4, "故障复位");
		msgType.put(5, "消音");
		msgType.put(6, "自检");
		msgType.put(7, "信号查询");
		msgType.put(8, "复位");
		msgType.put(9, "注册");
		msgType.put(11, "注销");

		paramType.clear();
		paramType.put(0x01, "燃气浓度");
		paramType.put(0x02, "水压");
		paramType.put(0x03, "液位");
		paramType.put(0x04, "温度");
		paramType.put(0x06, "剩余电流");
		paramType.put(0x07, "485 通信速率");
		paramType.put(0x08, "本机地址");
		paramType.put(0x09, "接线方式");
		paramType.put(0x0A, "A 相电流");
		paramType.put(0x0B, "B 相电流");
		paramType.put(0x0C, "C 相电流");
		paramType.put(0x0D, "A 相电压");
		paramType.put(0x0E, "B 相电压");
		paramType.put(0x0F, "C 相电压");
		paramType.put(0x10, "单相电压");
		paramType.put(0x11, "单相电流");
		paramType.put(0x12, "选择开关控制");

		paramType.put(0x13, "开关量输出状态");
		paramType.put(0x14, "为用水的配置信息");
		paramType.put(0x15, "电量百分比");

		statusType.clear();
		statusType.put(0, "预热状态");
		statusType.put(1, "检测");
		statusType.put(2, "报警");
		statusType.put(3, "故障");
		statusType.put(4, "设备寿命超期");
	} 

	/**
	 * 计算校验和
	 * @param data
	 * @return
	 */
	public static String makeChecksum(String data) {
		if (data == null || data.equals("")) {
		 return "";
		}
		int total = 0;
		int len = data.length();
		int num = 0;
		while (num < len) {
		 String s = data.substring(num, num + 2);
		 System.out.println(s);
		 total += Integer.parseInt(s, 16);
		 num = num + 2;
		}
		/**
		 * 用256求余最大是255，即16进制的FF
		 */
		int mod = total % 256;
		String hex = Integer.toHexString(mod);
		len = hex.length();
		// 如果不够校验位的长度，补0,这里用的是两位校验
		if (len < 2) {
		 hex = "0" + hex;
		}
		return hex.toUpperCase();
	}
	/**
	 * 平台下发消音指令组包
	 * @return
	 */
	public static String downDevData(){
		
		long st =new Date().getTime()/1000;
		int wmind = (int)(st%65535);
		String headAndData = "90"+GwUtil.IntToHex(wmind, 4)+"920001FFFF0000";
		return headAndData+makeChecksum(headAndData);
	}
	/**
	 * 解析海康烟感设备的数据
	 * @param hexStr
	 * @return
	 */
	public static AlarmHKData analysis_Smoke_Msg(String hexStr){
		AlarmHKData retData = new AlarmHKData();
		ParsingMessage par = new ParsingMessage();
		if(hexStr.substring(0,2).equals("07")){
			RegisterMsg reg = par.parseRegisterMsg(hexStr);
			retData.setMsgType(1);
			retData.setMsgTypeText(reg.byMsgType);
			retData.setOnline(reg.byMsgType);
			
			retData.setSignalStrength(GwUtil.HexToInt(reg.wRsrp)+"");
			retData.setSignalSNR(GwUtil.HexToInt(reg.bySnr)+"");
			retData.setSignalECL(GwUtil.HexToInt(reg.byEcl)+"");
			//retData.setRssi(GwUtil.HexToInt(reg.byPCI)+"");

			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
			retData.setOid(Long.toString(new Date().getTime()));
			retData.setAt(df.format(new Date()));
			
		}else{
			Protocol_Header head = par.parseMsgHead(hexStr.substring(0,40));
			if(head.byMessageId=="心跳"||head.byMessageId=="报警"||head.byMessageId=="消音"||head.byMessageId=="故障"||head.byMessageId=="配置参数上报")
			{
				MultichannelService mu = par.parseMultiChanSer(hexStr.substring(40));
				if(head.byMessageId=="心跳"){
					retData.setMsgType(1);
				}else{
					retData.setMsgType(2);
					retData.setAlarmDetail(head.byMessageId);
				}
				retData.setMsgTypeText(head.byMessageId);
				retData.setSignalStrength(GwUtil.HexToInt(head.wRsrp)+"");
				retData.setSignalSNR(GwUtil.HexToInt(head.bySnr)+"");
				retData.setSignalECL(GwUtil.HexToInt(head.byEcl)+"");
				//retData.setRssi(GwUtil.HexToInt(head.byPCI)+"");
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				String sd = sdf.format(new Date(Long.parseLong(head.byTime+"000"))); // 时间戳转换日期
				retData.setOid(head.byTime);
				retData.setAt(sd);
				
			

				if(head.byMessageId=="报警"){
					retData.setAlarmType(2);
					retData.setStreamId("fireAlarm");
				}else if(head.byMessageId=="消音"){
					retData.setAlarmType(6);
					retData.setStreamId("clean");
				}else if(head.byMessageId=="故障"){
					retData.setAlarmType(3);
					retData.setStreamId("sensor");
					retData.setAlarmDetail("传感器故障");
				}


				if(mu.ChaneParaBodyLt.size()>0)
				{
					for (ChannelParamBody var : mu.ChaneParaBodyLt) 
					{
						if(var.wEventType=="故障类型"){
							if(var.wEventValue.contains("低电压")){
								retData.setAlarmType(5);
								retData.setStreamId("power");
								retData.setAlarmDetail("低电压");
							}else if(var.wEventValue.contains("设备被拆下")){
								retData.setAlarmType(4);
								retData.setStreamId("integral");
								retData.setAlarmDetail("设备被拆下");
							}
						}else if(var.wEventType=="报警类型"){
							if(!var.wEventValue.isEmpty()){
								retData.setAlarmDetail(var.wEventValue);
							}	
						}
						if(var.wParamType=="电量百分比")
						{
							retData.setBatteryPower(var.wParamValue+""); 
						}else if(var.wParamType=="燃气浓度"){
							retData.setSmokeScope(var.wParamValue+""); 
						}
					}
				}




			}else{
				OneChannelBody oneChan = par.parseOneChanSer(hexStr.substring(40));
				if(head.byMessageId=="自检"){
					retData.setMsgType(1);
					retData.setMsgTypeText(oneChan.byMsgType);
					retData.setSignalStrength(GwUtil.HexToInt(head.wRsrp)+"");
					retData.setSignalSNR(GwUtil.HexToInt(head.bySnr)+"");
					retData.setSignalECL(GwUtil.HexToInt(head.byEcl)+"");
					//retData.setRssi(GwUtil.HexToInt(head.byPCI)+"");
					SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
					String sd = sdf.format(new Date(Long.parseLong(head.byTime+"000"))); // 时间戳转换日期
					retData.setOid(head.byTime);
					retData.setAt(sd);
					retData.setSelfCheck("自检");
				}
			}
		}


		return retData;
   }

	public static int byteToInt(byte b) {   
		//Java 总是把 byte 当做有符处理；我们可以通过将其和 0xFF 进行二进制与得到它的无符值 
		return b & 0xFF;   
		} 
	/**
	 * 解析上报协议头
	 * @param bs
	 */
	public  Protocol_Header parseMsgHead(String hexStr) {
	
			Protocol_Header head = new Protocol_Header();
			byte[] msg = GwUtil.HexString2Bytes(hexStr);
		
			head.byMessageId = messageIdDic.get(byteToInt(msg[0]));
			head.byFixedSign= hexStr.substring(2,4);
			head.byDevType = devTypeDic.get(byteToInt(msg[2]));
			head.byMac = hexStr.substring(6,18);
			head.byTime = String.valueOf(GwUtil.DWord2long(GwUtil.subByte(msg,9,4)));
			head.byDevTypeEx = hexStr.substring(26,28);
			head.byResl =  hexStr.substring(28,30);
			head.byPCI = hexStr.substring(30,32);
			head.bySnr = hexStr.substring(32,34);
			head.byEcl=hexStr.substring(34,36);
			head.wRsrp = hexStr.substring(36,40);
			return head;
	}
	 
	/**
	 * 解析多通道头
	 * @param hexStr
	 * @return
	 */
    public MultichannelService parseMultiChanSer(String hexStr){
		MultichannelService multiChan = new MultichannelService();
		byte[] msg = GwUtil.HexString2Bytes(hexStr);
        multiChan.byRes = hexStr.substring(0,2);
		multiChan.byMsgType = msgType.get(byteToInt(msg[1]));
		multiChan.byRes2 = hexStr.substring(4,8);
		multiChan.wLen = GwUtil.byteBE1Int(GwUtil.subByte(msg,4,2));
		multiChan.wChanRscType = hexStr.substring(12,16);
		multiChan.wChanRscValue =GwUtil.byteBE1Int(GwUtil.subByte(msg,8,2));
		
		int bodyCout = (multiChan.wLen-5)/14;
		for (int i = 0; i < bodyCout; i++) {
			ChannelParamBody paraBody =	parseChanParaBody(hexStr.substring(20+(bodyCout-1)*28,20+bodyCout*28));
			multiChan.ChaneParaBodyLt.add(paraBody);
		}
		return multiChan;
	}

	/**
	 * 解析无通道
	 * @param hexStr
	 * @return
	 */
    public OneChannelBody parseOneChanSer(String hexStr){
		OneChannelBody multiChan = new OneChannelBody();
		byte[] msg = GwUtil.HexString2Bytes(hexStr);
        multiChan.byRes = hexStr.substring(0,2);
		multiChan.byMsgType = msgType.get(byteToInt(msg[1]));
		multiChan.byRes1 = hexStr.substring(4,8);
		multiChan.wRes2 = GwUtil.byteBE1Int(GwUtil.subByte(msg,4,2));
		
		return multiChan;
	}

	public RegisterMsg parseRegisterMsg(String hexStr){
		RegisterMsg regMsg = new RegisterMsg();
		byte[] msg = GwUtil.HexString2Bytes(hexStr);
		
		regMsg.byMessageId = messageIdDic.get(byteToInt(msg[0]));
		regMsg.byFixedSign= hexStr.substring(2,4);
		regMsg.byDevType = devTypeDic.get(byteToInt(msg[2]));
		regMsg.byMac = hexStr.substring(6,18);
		regMsg.byYear = "20"+byteToInt(msg[9]);
		regMsg.byMonth =byteToInt(msg[10])+"";
		regMsg.byDay =byteToInt(msg[11])+"";
		regMsg.byRes1 =  hexStr.substring(24,26);
		regMsg.byDevTypeEx = hexStr.substring(26,28);
		regMsg.byRes2 =  hexStr.substring(28,30);
		regMsg.byPCI = hexStr.substring(30,32);
		regMsg.bySnr = hexStr.substring(32,34);
		regMsg.byEcl=hexStr.substring(34,36);
		regMsg.wRsrp = hexStr.substring(36,40);
		regMsg.byStatus =  statusType.get(byteToInt(msg[20]));
		regMsg.byMsgType= msgType.get(byteToInt(msg[21]));
		regMsg.byRes = hexStr.substring(44,52);
		regMsg.byQCCID = new String(GwUtil.subBytes(msg, 26, 20));
		return regMsg;
	}
	/**
	 * 解析多通道参数体
	 * @param hexStr
	 * @return
	 */
	public ChannelParamBody parseChanParaBody(String hexStr){
		ChannelParamBody channParaBody = new ChannelParamBody();
		byte[] msg = GwUtil.HexString2Bytes(hexStr);
		channParaBody.wType = hexStr.substring(0,4);
		channParaBody.wValue = hexStr.substring(4,8);
    
		
	   if(GwUtil.byteBE1Int(GwUtil.subByte(msg,4,2))==0x62){
		channParaBody.wEventType="无状态类型";
		channParaBody.wEventValue = "";
	   }else if(GwUtil.byteBE1Int(GwUtil.subByte(msg,4,2))==0x63){
		channParaBody.wEventType="故障类型";
		channParaBody.wEventValue = analyze63(GwUtil.subByte(msg,8,2));
	   }else if(GwUtil.byteBE1Int(GwUtil.subByte(msg,4,2))==0x64){
		channParaBody.wEventType="报警类型";
		channParaBody.wEventValue = analyze64(GwUtil.subByte(msg,8,2));
	   }
	   channParaBody.wEventValueHight = hexStr.substring(12,16);
	   channParaBody.wParamType = paramType.get(GwUtil.byteBE1Int(GwUtil.subByte(msg,10,2)));
	   channParaBody.wParamValue = GwUtil.byteBE1Int(GwUtil.subByte(msg,12,2));
		


		return channParaBody;
	}

	public static String analyze63(byte[] aByte)
	{
		StringBuilder reStr = new StringBuilder();

		byte[] cByte = GwUtil.HexString2Bytes("0102040810204080");
		String[] str = { "寿命超期", "传感器短路/断路故障", "传感器失联故障", "低电压", "设备被拆下", "迷宫污染", "用电传感器故障", "通信故障", "传感器故障", "欠压故障", "过压故障", "过流故障", "缺相故障", "错相故障", "", ""};
		for (int i = 1; i > -1; i--)
		{
			for (int j = 0; j < 8; j++)
			{
				int a = aByte[i] & cByte[j];
				if (a != 0)
				{
					reStr.append(str[(1 - i) * 8 + j]);
				}
				else
				{
					reStr.append("");
				}
			}
		}
		return reStr.toString();
	}

	public static String analyze64(byte[] aByte)
	{
		StringBuilder reStr = new StringBuilder();

		byte[] cByte = GwUtil.HexString2Bytes("0102040810204080");
		String[] str = { "烟雾报警", "燃气报警", "剩余电流报警", "温度报警", "水压报警", "液位报警", "", "", "", "", "", "", "", "", "", ""};
		for (int i = 1; i > -1; i--)
		{
			for (int j = 0; j < 8; j++)
			{
				int a = aByte[i] & cByte[j];
				if (a != 0)
				{
					reStr.append(str[(1 - i) * 8 + j]);
				}
				else
				{
					reStr.append("");
				}
			}
		}
		return reStr.toString();
	}
	
	
}
